package com.wskj.supermarket.util;

import java.io.UnsupportedEncodingException;
import java.security.NoSuchAlgorithmException;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;

/**
 * 
 * @author Administrator
 *  1、目标
完成对request请求参数的加密
2、设计的知识点
a、filter、servlet、装饰器模式
3、遇到问题
在写这个程序的时候遇到一点一点小问题；什么问题呢？
a、就是一个关于HttpServletRequestWrapper和servletRequestWrapper的问题；
b、HttpServletRequestWrapper实现的是HttpServletRequest接口而后者则是实现的是ServletRequest接口；
c、当第一次请求的时候，系统默认的请求是类型是requestFacade的一个类型，这个requestFacade类型实现了HttpServletRquest的接口；
d、我第一次用的时候，我写的EncryptionReqestWrapper类是继承了ServletRequstWrapper的类的；虽然程序没报错，一运行却报错了，报的是not-request和respone；在网上查了下；大概的意思就是传入的request的类型不对；
e、所以我做了一个实验我以为是ServletRequest接口的实现类不能作为参数传入dofilter中的request作为参数；但是我实验结果是可以的程序不报错；但是精度会损失，就向父类接收子类，精度会丢失，后来没办法只能传入一个HttpServletReqest的类型给doFIlter中的request；程序没报错；正确运行；
f、补充下因为使用filter拦截所以doFilter中的request是实现了HttpServletRequest接口的requestFacade；只要保持传入的参数最终类型一致就可以了；
a、核心代码
 */

/**
 * 可以全部加密 ,也可以只加密请求中 name=password 的数据 ,其他的数据正常返回
 * 
 * @author Administrator
 *
 */
public class EncryptionReqestWrapper extends HttpServletRequestWrapper {

	public EncryptionReqestWrapper(HttpServletRequest request) {
		super(request);
		// TODO Auto-generated constructor stub
	}

	/**
	 * 对获取单个的参数值进行加密
	 */
	@Override
	public String getParameter(String name) {
		try {

			if ("password".equals(name)) {

				return MD5Util.EncoderByMd5(super.getParameter(name));
			} else {
				return super.getParameter(name);
			}

		} catch (NoSuchAlgorithmException e) {
			e.printStackTrace();
		} catch (UnsupportedEncodingException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return null;
	}

	/**
	 * 对多个的参数进行加密处理
	 */

	@Override
	public String[] getParameterValues(String name) {
		// TODO Auto-generated method stub
		/**
		 * 具体的加密算法 ,对其中的每个参数都进行加密处理
		 */

		if ("password".equals(name)) {
			String[] parameterValues = super.getParameterValues(name);
			for (int i = 0; i < parameterValues.length; i++) {
				try {
					parameterValues[i] = MD5Util.EncoderByMd5(parameterValues[i]);
				} catch (NoSuchAlgorithmException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				} catch (UnsupportedEncodingException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
			return parameterValues;
		} else {
			return super.getParameterValues(name);
		}

	}

	@Override
	public Map<String, String[]> getParameterMap() {
		// 遍历原始的请求参数
		for (Map.Entry<String, String[]> m : super.getParameterMap().entrySet()) {

			if ("password".equals(m.getKey())) {
				for (int i = 0; i < m.getValue().length; i++) {
					// 加密值
					// 仅仅加密 属性为password的值 ,其他的不加密
					try {
						m.getValue()[i] = MD5Util.EncoderByMd5(m.getValue()[i]);
					} catch (NoSuchAlgorithmException e) {
						e.printStackTrace();
					} catch (UnsupportedEncodingException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
				}
			}
		}
		return super.getParameterMap();
	}

}
